import 'dart:ui';

import '../utils/color_utils.dart';
import 'base/base_effect.dart';
import 'effect_template.dart';

class Effect07 extends EditableAnimationEffect {
  @override
  List<Color> get defaultColors => [const Color(0xFF00FFFF)];

  @override
  EffectType get effectTyp => EffectType.effect07;

  @override
  bool get enableAngle => true;

  @override
  RangeArgument get angleRange => RangeArgument(-180, 180, 0);

  @override
  bool get enableColorWidth => true;

  @override
  RangeArgument get colorWidthRange => RangeArgument(10, 20, 20);

  @override
  bool get enableDensity => false;

  @override
  bool get enableEditColor => false;

  @override
  bool get enableSpeed => true;

  @override
  RangeArgument get speedRange => RangeArgument(0, 9, 7);

  @override
  Future<List<List<List<Color>>>> getFrames({EffectOperation? operation}) {
    Color color = getColorList(effectOperation: operation).first;

    List<Color> colorList = [
      const Color(0xFF000000),
      color,
      const Color(0xFFFFFFFF),
      color,
      const Color(0xFF000000)
    ];

    int colorWidth = operation?.colorWidth ?? colorWidthRange.defaultValue;
    double perSize = colorWidth / colorList.length;

    List<double> stops = List.generate(colorList.length, (index) => perSize*index);

    int angle = getAngle(effectOperation: operation);
    Size rotateSize = getRotateSize(angle: angle);
    double newWidth = rotateSize.width;
    double newHeight = rotateSize.height;
    int totalFrame = newHeight.toInt();

    List<Color> singleColumn = [];
    // List<int> posYList = [0,0,1,1,2,3,4,5,6,7,9,11,12];
    List<List<List<Color>>> frames = [];

    for (int i = 0; i < totalFrame; i++) {
      if(i<=colorWidth){
        var gradientColor = ColorUtils.lerpGradient(colorList, stops, i.toDouble());
        singleColumn.add(gradientColor);
      }else{
        singleColumn.add(const Color(0xFF000000));
      }
    }

    for (int i = 0; i < totalFrame; i++) {
      List<List<Color>> frame = [];
      for (int j = 0; j < newHeight; j++) {
        List<Color> columns = [];
        for (int z = 0; z < newHeight; z++) {
          columns.add(singleColumn[(i + z) % singleColumn.length]);
        }
        frame.add(columns);
      }
      frames.add(frame);
    }

    if (angle != 0) {
      List<List<List<Color>>> angleFrames = getRotateFrames(
        frames,
        angle: angle,
        newWidth: newWidth,
        newHeight: newHeight,
      );
      return Future.value(angleFrames);
    } else {
      return Future.value(frames);
    }
  }

  @override
  bool get isFixedColorCount => true;

  @override
  Size get size => const Size(24, 24);
}